import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart';
import 'Routes.dart';

class HiRouteParser extends RouteInformationParser<Routes> {
  @override
  Future<Routes> parseRouteInformation(RouteInformation routeInformation) {
    Routes t;
    for (Routes route in Routes.values) {
      if (routeInformation.location == route.toString()) {
        t = route;
        break;
      }
    }
    return SynchronousFuture(t);
  }

  @override
  RouteInformation restoreRouteInformation(Routes configuration) {
    return RouteInformation(location: configuration.toString());
  }
}

class HiRouteDelegate extends RouterDelegate<Routes>
    with PopNavigatorRouterDelegateMixin<Routes>, ChangeNotifier {

  List<Routes> _stack = <Routes>[];

  static HiRouteDelegate of(BuildContext context) {
    final delegate = Router.of(context).routerDelegate;
    assert(delegate is HiRouteDelegate, 'Delegate type must match');
    return delegate as HiRouteDelegate;
  }

  HiRouteDelegate({
    @required this.onGenerateRoute,
  });

  final RouteFactory onGenerateRoute;

  @override
  GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

  @override
  Routes get currentConfiguration => _stack.isNotEmpty ? _stack.last : null;

  List<Routes> get stack => List.unmodifiable(_stack);

  void push(Routes newRoute) {
    _stack.add(newRoute);
    notifyListeners();
  }

  void remove(Routes routeName) {
    _stack.remove(routeName);
    notifyListeners();
  }

  void replaceAll(Routes routeName) {
    _stack = <Routes>[routeName];
    notifyListeners();
  }

  @override
  Future<void> setInitialRoutePath(Routes configuration) {
    return setNewRoutePath(configuration);
  }

  @override
  Future<void> setNewRoutePath(Routes configuration) {
    _stack
      ..clear()
      ..add(configuration);
    return SynchronousFuture<void>(null);
  }

  bool _onPopPage(Route<dynamic> route, dynamic result) {
    if (_stack.isNotEmpty) {
      if (_stack.last.toString() == route.settings.name) {
        _stack.remove(_stack.last);
        notifyListeners();
      }
    }
    return route.didPop(result);
  }

  @override
  Widget build(BuildContext context) {
    print('${describeIdentity(this)}.stack: $_stack');
    return Navigator(
      key: navigatorKey,
      onPopPage: _onPopPage,
      pages: _stack.map((e) => getPage(e)).toList(),
    );
  }
}